package com.bb.blog.security.resource;

import com.bb.blog.web.exception.ServerException;
import com.bb.blog.web.model.CommonResponse;
import com.nimbusds.oauth2.sdk.GrantType;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;


@FeignClient(contextId = "auth-server.login" , name = "auth-server", fallbackFactory = LoginClientServiceFallbackFactory.class)
interface LoginClientService {
    /**
     * 登录用的远程调用
     */
    @RequestMapping(method = RequestMethod.POST, value = "/oauth/token")
    CommonResponse<Object> login(@RequestParam("client_id") String clientId,
                                 @RequestParam("client_secret") String clientSecret,
                                 @RequestParam("username") String username,
                                 @RequestParam("password") String password,
                                 @RequestParam("grant_type") String grantType);

    /**
     * 刷新token
     */
    @RequestMapping(method = RequestMethod.POST, value = "/oauth/token")
    CommonResponse<Object> refreshToken(@RequestParam("client_id") String clientId,
                                        @RequestParam("client_secret") String clientSecret,
                                        @RequestParam("refresh_token") String refreshToken,
                                        @RequestParam("grant_type") String grantType);

}

@Controller
@Slf4j
public class LoginEndpoint {
    private final LoginClientService loginClientService;

    @Value("${spring.security.oauth2.resourceserver.opaquetoken.client-id}")
    String clientId;
    @Value("${spring.security.oauth2.resourceserver.opaquetoken.client-secret}")
    String clientSecret;

    public LoginEndpoint(LoginClientService loginClientService) {
        log.info(LoginEndpoint.class + "开始初始化了");
        this.loginClientService = loginClientService;
    }


    @PostMapping(path = "/auth/login")
    @ResponseBody
    public CommonResponse login(@RequestParam("username") String username,
                                @RequestParam("password") String password) {
        if (StringUtils.isEmpty(clientId) || StringUtils.isEmpty(clientSecret)) {
            throw new ServerException(500, "系统配置异常,没有找到client-id与client-secret");
        }
        CommonResponse<Object> response = loginClientService.login(
            clientId, clientSecret, username, password, GrantType.PASSWORD.getValue());

        if (response == null) {
            throw new ServerException(500, "登录异常");
        }
        return response;
    }

    @RequestMapping(method = RequestMethod.POST, value = "/auth/refreshToken")
    @ResponseBody
    public CommonResponse refreshToken(@RequestParam("refresh_token") String refreshToken) {
        CommonResponse<Object> response = loginClientService.refreshToken(
            clientId, clientSecret, refreshToken, GrantType.REFRESH_TOKEN.getValue());

        if (response == null) {
            throw new ServerException(500, "刷新token异常");
        }
        return response;
    }


}

@Component
@Slf4j
class LoginClientServiceFallbackFactory implements FallbackFactory<LoginClientService> {

    @Override
    public LoginClientService create(Throwable cause) {
        log.info("认证服务异常 ----------> 服务降级", cause);
        return new LoginClientService() {
            @Override
            public CommonResponse<Object> login(String clientId, String clientSecret, String username, String password, String grantType) {
                log.info("登录服务降级 ----------> ");
                return null;
            }

            @Override
            public CommonResponse<Object> refreshToken(String clientId, String clientSecret, String refreshToken, String grantType) {
                log.info("refreshToken 服务降级 ---------> ");
                return null;
            }
        };
    }
}



